Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define __assume(c) { if (!(c)) { __builtin_unreachable(); } }
- template <typename T> using arg_t = const T & __restrict;
- template <typename F>
- static constexpr void validate_type ()
- {
- using traits = float_traits<F>;
- static_assert((traits::significand_bits + traits::exponent_bits + 1) == (sizeof(traits) * 8), "floating-point format mismatch");
- static_assert(traits::significand_offset == 0, "floating-point format assumption error");
- static_assert(traits::exponent_offset == traits::significand_bits, "floating-point format assumption error");
- static_assert(traits::sign_offset == (traits::significand_bits + traits::exponent_bits), "floating-point format assumption error");
- }
- template <typename Fout, typename Fin>
- Fout convert_to (Fin in) __attribute__ ((const, pure, flatten))
- {
- if constexpr (std::is_same_v<Fout, Fin>)
- {
- return in;
- }
- using Tout = float_traits<Fout>;
- using Tin = float_traits<Fin>;
- validate_type<Fout>();
- validate_type<Fin>();
- using uint_out = uintb<sizeof(Fout)>;
- using uint_in = uintb<sizeof(Fin)>;
- static_assert(sizeof(uint_out) == sizeof(Fout), "uint_out / Fout size mismatch");
- static_assert(sizeof(uint_in) == sizeof(Fin), "uint_in / Fin size mismatch");
- union in_union_t
- {
- const Fin value_;
- struct data
- {
- uint_in significand : Tin::significand_bits;
- uint_in exponent : Tin::exponent_bits;
- uint_in sign : 1;
- } const data_;
- in_union_t (arg_t<Fin> val) : value_(val) {}
- } const in_expand = {in};
- union out_union_t
- {
- const Fout value_;
- struct data
- {
- uint_out significand : Tout::significand_bits;
- uint_out exponent : Tout::exponent_bits;
- uint_out sign : 1;
- data (arg_t<in_union_t> in) :
- significand(({ __assume(in.data_.significand < bit_val<Tin::significand_bits>); in.data_.significand; })),
- exponent(({ __assume(in.data_.exponent < bit_val<Tin::exponent_bits>); in.data_.exponent; })),
- sign(({ __assume(in.data_.sign <= 1); in.data_.sign; }))
- {}
- } const data_;
- out_union_t (arg_t<in_union_t> in) : data_(in) {}
- };
- return out_union_t{in_expand}.value_;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement